/**
 * @file
 * Map implentation
 */

#ifndef __MAP_H
#define __MAP_H

#ifndef __RB_TREE_H
# error "Please include rb_tree.h before map.h"
#endif

struct map_kv_pair {
    struct rb_tree_node me;
    union {
        void *v_value;
        int   i_value;
    } value;
    unsigned int length;
    char key[0];
};

struct map {
  unsigned int size;
  void (*_free)(void*);
  struct rb_tree rb;
};

/**
 * map_init - initialize the map instance
 */
inline void map_init(struct map *m, void (*_free)(void*));

/**
 */
inline void map_clear(struct map *m);

/**
 */
#define create_map_add(func, type)                                      \
  inline void func(struct map *m, void *key, unsigned int length, type value);

create_map_add(map_add_void, void*)
create_map_add(map_add_int, int)

/**
 */
#define create_map_get(func, type)                                      \
  inline int func(struct map *m, void *key, unsigned int length, type *value);

create_map_get(map_get_void, void*)
create_map_get(map_get_int, int)

/**
 */
#define create_map_delete(func, type)                                   \
  inline int func(struct map *m, void *key, unsigned int length, type *value);

create_map_delete(map_delete_void, void*)
create_map_delete(map_delete_int, int)

/**
 */
inline void map_begin(struct map *m, struct map_kv_pair **pair);

/**
 */
#define create_map_next(func, type)                                     \
  inline int func(struct map *m, struct map_kv_pair **pair, type *value);

create_map_next(hsh_next_void, void*)
create_map_next(hsh_next_int, int)

#endif /* __MAP_H */
